package com.yc.framework.web.service;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yc.common.core.domain.entity.SysUser;
import com.yc.common.exceptions.captcha.CaptchaException;
import com.yc.common.exceptions.captcha.CaptchaExpireException;
import com.yc.common.exceptions.user.UserRegisterException;
import com.yc.common.core.domain.model.RegisterBody;
import com.yc.system.mapper.SysRoleMapper;
import com.yc.system.mapper.SysUserMapper;
import com.yc.system.mapper.SysUserRoleMapper;
import com.yc.system.service.CaptchaService;
import com.yc.common.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.Date;
import java.util.regex.Pattern;

@Service
public class SysRegisterService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    // 正则表达式
    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";

    @Transactional(rollbackFor = SQLException.class)
    public void register(RegisterBody registerBody) {
        // 验证码校验
        try {
            captchaService.validateCaptcha(registerBody.getPhone(), registerBody.getCaptchaId(), registerBody.getCode());
        } catch (CaptchaException | CaptchaExpireException e) {
            throw e;
        }

        // 用户名校验
        String username = registerBody.getUsername();
        if (StringUtil.isEmpty(username)) {
            throw new UserRegisterException("请输入用户名");
        }
        if (username.length() < 2 || username.length() > 20) {
            throw new UserRegisterException("用户名长度必须在2-20个字符之间");
        }

        // 手机号校验
        String phone = registerBody.getPhone();
        if (StringUtil.isEmpty(phone)) {
            throw new UserRegisterException("请输入手机号");
        }
        if (!Pattern.matches(PHONE_REGEX, phone)) {
            throw new UserRegisterException("手机号格式不正确");
        }

        // 密码校验
        String password = registerBody.getPassword();
        String confirmPassword = registerBody.getConfirmPassword();
        if (StringUtil.isEmpty(password)) {
            throw new UserRegisterException("请输入密码");
        }
        if (StringUtil.isEmpty(confirmPassword)) {
            throw new UserRegisterException("请确认密码");
        }
        if (!password.equals(confirmPassword)) {
            throw new UserRegisterException("两次输入的密码不一致");
        }

        synchronized (RegisterBody.class) {
            LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
            // 检查用户名是否已存在
            lqw.eq(SysUser::getUserName, username);
            if (sysUserMapper.selectOne(lqw) != null) {
                throw new UserRegisterException("用户名已存在");
            }

            // 检查手机号是否已存在
            lqw.eq(SysUser::getPhonenumber, phone);
            if (sysUserMapper.selectOne(lqw) != null) {
                throw new UserRegisterException("手机号已被注册");
            }
        }


        // 注册用户
        SysUser user = new SysUser();

        long id = IdUtil.getSnowflake().nextId();
        user.setId(id);
        user.setUserName(username);
        user.setNickName(username);
        user.setPhonenumber(phone);
        user.setPassword(passwordEncoder.encode(password));
        user.setStatus("0");  // 正常状态
        user.setCreateTime(new Date());

        sysUserMapper.insert(user);

        //分配默认角色
        sysUserRoleMapper.insertUserRole(id);
    }
}